
#include <ttg/libs.h>

#include "ArgsParser.h"
#include "serialFibonacci.h"
#include "tbbFibonacci_Reduce.h"
#include "tbbFibonacci_Scan.h"
#include "ttgFibonacci.h"

const int IntSize = 16 * 1024;

int main(int argc, char *argv[])
{
	//Initing.
	ArgsParser args(argc, argv);
	ttg::services::ServiceBase::getRef()->start();
	tbb::task_scheduler_init init(tbb::task_scheduler_init::automatic);
	//tbb::task_scheduler_init init(1);
	printf("TBB vs TTG: Fibonacci\n");
	printf("CPU type: %s\n\n", ttg::services::CPUAnalyzer::getRef()->getCPUInfo());
	//Serial version.
	printf("Serial version ...\n");
	std::pair<BigUnsignedInt<IntSize>, double> serialResult
		= serialFibonacci<BigUnsignedInt<IntSize>>(args.getN());
	printf("   Result: %s\n   Elapsed time: %f seconds\n",
		   serialResult.first.toString().c_str(), serialResult.second);
	//Intel TBB version (via tbb::parallel_reduce()).
	printf("tbb::parallel_reduce ...\n");
	std::pair<BigUnsignedInt<IntSize>, double> tbbReduceResult
		= tbbFibonacci_Reduce<BigUnsignedInt<IntSize>>(args.getN());
	printf("   Result: %s\n   Elapsed time: %f seconds\n",
		   tbbReduceResult.first.toString().c_str(), tbbReduceResult.second);
	//Intel TBB version (via tbb::parallel_scan()).
	printf("tbb::parallel_scan ...\n");
	std::pair<BigUnsignedInt<IntSize>, double> tbbScanResult
		= tbbFibonacci_Scan<BigUnsignedInt<IntSize>>(args.getN());
	printf("   Result: %s\n   Elapsed time: %f seconds\n",
		   tbbScanResult.first.toString().c_str(), tbbScanResult.second);
	//ttgLib version.
	printf("ttg::pipeline ...\n");
	std::pair<BigUnsignedInt<IntSize>, double> ttgResult
		= ttgFibonacci<BigUnsignedInt<IntSize>>(args.getN());
	printf("   Result: %s\n   Elapsed time: %f seconds\n",
		   ttgResult.first.toString().c_str(), ttgResult.second);
	return 0;
}
